using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TxTReader.Core;

namespace TxTReader.Core
{
    /// <summary>
    /// 搜索结果
    /// </summary>
    public class SearchResult
    {
        public int LineNumber { get; set; }
        public int ColumnIndex { get; set; }
        public string Content { get; set; } = string.Empty;
        public int MatchLength { get; set; }
        public long FilePosition { get; set; }
        
        /// <summary>
        /// 显示文本（用于搜索结果列表显示）
        /// </summary>
        public string DisplayText => $"第 {LineNumber} 行，第 {ColumnIndex} 列";
        
        /// <summary>
        /// 预览文本（显示匹配行的内容）
        /// </summary>
        public string PreviewText => Content.Length > 100 ? Content.Substring(0, 100) + "..." : Content;
    }

    /// <summary>
    /// 搜索选项
    /// </summary>
    public class SearchOptions
    {
        public bool CaseSensitive { get; set; } = false;
        public bool WholeWord { get; set; } = false;
        public bool UseRegex { get; set; } = false;
        public int MaxResults { get; set; } = 1000;
    }

    /// <summary>
    /// 搜索引擎
    /// </summary>
    public class SearchEngine
    {
        private readonly IFileReader _fileReader;
        private readonly List<SearchResult> _searchResults;
        private int _currentResultIndex = -1;
        private CancellationTokenSource? _cancellationTokenSource;

        public IReadOnlyList<SearchResult> SearchResults => _searchResults.AsReadOnly();
        public int CurrentResultIndex => _currentResultIndex;
        public SearchResult? CurrentResult => _currentResultIndex >= 0 && _currentResultIndex < _searchResults.Count 
            ? _searchResults[_currentResultIndex] 
            : null;

        public bool IsSearching => _cancellationTokenSource != null && !_cancellationTokenSource.Token.IsCancellationRequested;

        public event EventHandler<SearchCompletedEventArgs>? SearchCompleted;
        public event EventHandler<SearchProgressEventArgs>? SearchProgress;
        public event EventHandler<SearchResultFoundEventArgs>? SearchResultFound;

        public SearchEngine(IFileReader fileReader)
        {
            _fileReader = fileReader;
            _searchResults = new List<SearchResult>();
        }

        /// <summary>
        /// 停止当前搜索
        /// </summary>
        public void StopSearch()
        {
            _cancellationTokenSource?.Cancel();
        }

        /// <summary>
        /// 执行搜索
        /// </summary>
        /// <param name="searchText">搜索文本</param>
        /// <param name="options">搜索选项</param>
        public async Task SearchAsync(string searchText, SearchOptions options)
        {
            if (string.IsNullOrEmpty(searchText) || !_fileReader.IsFileOpen)
                return;

            // 取消之前的搜索
            _cancellationTokenSource?.Cancel();
            _cancellationTokenSource = new CancellationTokenSource();
            var cancellationToken = _cancellationTokenSource.Token;

            _searchResults.Clear();
            _currentResultIndex = -1;

            try
            {
                var totalLines = _fileReader.TotalLines;
                var processedLines = 0;

                // 分块搜索以提高性能
                const int batchSize = 100;
                for (int startLine = 1; startLine <= totalLines; startLine += batchSize)
                {
                    // 检查取消请求
                    cancellationToken.ThrowIfCancellationRequested();

                    var endLine = Math.Min(startLine + batchSize - 1, (int)totalLines);
                    var lines = await _fileReader.GetLinesAsync(startLine, endLine - startLine + 1);

                    foreach (var line in lines)
                    {
                        // 检查取消请求
                        cancellationToken.ThrowIfCancellationRequested();

                        var results = SearchInLine(line, searchText, options);
                        
                        // 即时添加结果并触发事件
                        foreach (var result in results)
                        {
                            _searchResults.Add(result);
                            OnSearchResultFound(new SearchResultFoundEventArgs(result));
                        }
                        
                        processedLines++;

                        // 限制结果数量
                        if (_searchResults.Count >= options.MaxResults)
                        {
                            break;
                        }
                    }

                    // 报告进度
                    var progress = (double)processedLines / totalLines * 100;
                    OnSearchProgress(new SearchProgressEventArgs(progress, processedLines, (int)totalLines));

                    if (_searchResults.Count >= options.MaxResults)
                    {
                        break;
                    }
                }

                OnSearchCompleted(new SearchCompletedEventArgs(_searchResults.Count, searchText, _searchResults));
            }
            catch (OperationCanceledException)
            {
                // 搜索被取消，这是正常情况
                OnSearchCompleted(new SearchCompletedEventArgs(_searchResults.Count, searchText, _searchResults));
            }
            catch (Exception ex)
            {
                throw new SearchException($"搜索失败: {ex.Message}", ex);
            }
            finally
            {
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = null;
            }
        }

        /// <summary>
        /// 在单行中搜索
        /// </summary>
        /// <param name="line">文本行</param>
        /// <param name="searchText">搜索文本</param>
        /// <param name="options">搜索选项</param>
        /// <returns>搜索结果列表</returns>
        private List<SearchResult> SearchInLine(TextLine line, string searchText, SearchOptions options)
        {
            var results = new List<SearchResult>();
            var content = line.Content;

            if (!options.CaseSensitive)
            {
                content = content.ToLowerInvariant();
                searchText = searchText.ToLowerInvariant();
            }

            if (options.UseRegex)
            {
                // TODO: 实现正则表达式搜索
                return results;
            }

            var searchLength = searchText.Length;
            var startIndex = 0;

            while (true)
            {
                var index = content.IndexOf(searchText, startIndex, StringComparison.Ordinal);
                if (index == -1)
                    break;

                // 检查是否匹配整个单词
                if (options.WholeWord)
                {
                    var isWholeWord = IsWholeWordMatch(line.Content, index, searchLength);
                    if (!isWholeWord)
                    {
                        startIndex = index + 1;
                        continue;
                    }
                }

                results.Add(new SearchResult
                {
                    LineNumber = line.LineNumber,
                    ColumnIndex = index,
                    Content = line.Content,
                    MatchLength = searchLength,
                    FilePosition = line.FilePosition
                });
                
                System.Diagnostics.Debug.WriteLine($"SearchEngine.SearchInLine: 添加搜索结果，行号: {line.LineNumber}, 内容: {line.Content.Substring(0, Math.Min(50, line.Content.Length))}");

                startIndex = index + 1;

                // 限制每行结果数量
                if (results.Count >= 100)
                    break;
            }

            return results;
        }

        /// <summary>
        /// 检查是否为整个单词匹配
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="index">匹配位置</param>
        /// <param name="length">匹配长度</param>
        /// <returns>是否为整个单词</returns>
        private bool IsWholeWordMatch(string content, int index, int length)
        {
            var beforeChar = index > 0 ? content[index - 1] : ' ';
            var afterChar = index + length < content.Length ? content[index + length] : ' ';

            return !char.IsLetterOrDigit(beforeChar) && !char.IsLetterOrDigit(afterChar);
        }

        /// <summary>
        /// 跳转到下一个结果
        /// </summary>
        /// <returns>是否成功跳转</returns>
        public bool GoToNext()
        {
            if (_searchResults.Count == 0)
                return false;

            _currentResultIndex = (_currentResultIndex + 1) % _searchResults.Count;
            return true;
        }

        /// <summary>
        /// 跳转到上一个结果
        /// </summary>
        /// <returns>是否成功跳转</returns>
        public bool GoToPrevious()
        {
            if (_searchResults.Count == 0)
                return false;

            _currentResultIndex = _currentResultIndex <= 0 ? _searchResults.Count - 1 : _currentResultIndex - 1;
            return true;
        }

        /// <summary>
        /// 跳转到指定结果
        /// </summary>
        /// <param name="index">结果索引</param>
        /// <returns>是否成功跳转</returns>
        public bool GoToResult(int index)
        {
            if (index < 0 || index >= _searchResults.Count)
                return false;

            _currentResultIndex = index;
            return true;
        }

        /// <summary>
        /// 清除搜索结果
        /// </summary>
        public void ClearResults()
        {
            _searchResults.Clear();
            _currentResultIndex = -1;
        }

        /// <summary>
        /// 触发搜索完成事件
        /// </summary>
        protected virtual void OnSearchCompleted(SearchCompletedEventArgs e)
        {
            SearchCompleted?.Invoke(this, e);
        }

        /// <summary>
        /// 触发搜索进度事件
        /// </summary>
        protected virtual void OnSearchProgress(SearchProgressEventArgs e)
        {
            SearchProgress?.Invoke(this, e);
        }

        /// <summary>
        /// 触发搜索结果发现事件
        /// </summary>
        protected virtual void OnSearchResultFound(SearchResultFoundEventArgs e)
        {
            SearchResultFound?.Invoke(this, e);
        }
    }

    /// <summary>
    /// 搜索完成事件参数
    /// </summary>
    public class SearchCompletedEventArgs : EventArgs
    {
        public int ResultCount { get; }
        public string SearchText { get; }
        public List<SearchResult> Results { get; }

        public SearchCompletedEventArgs(int resultCount, string searchText, List<SearchResult> results = null)
        {
            ResultCount = resultCount;
            SearchText = searchText;
            Results = results ?? new List<SearchResult>();
        }
    }

    /// <summary>
    /// 搜索进度事件参数
    /// </summary>
    public class SearchProgressEventArgs : EventArgs
    {
        public double ProgressPercentage { get; }
        public int ProcessedLines { get; }
        public int TotalLines { get; }

        public SearchProgressEventArgs(double progressPercentage, int processedLines, int totalLines)
        {
            ProgressPercentage = progressPercentage;
            ProcessedLines = processedLines;
            TotalLines = totalLines;
        }
    }

    /// <summary>
    /// 搜索结果发现事件参数
    /// </summary>
    public class SearchResultFoundEventArgs : EventArgs
    {
        public SearchResult Result { get; }

        public SearchResultFoundEventArgs(SearchResult result)
        {
            Result = result;
        }
    }

    /// <summary>
    /// 搜索异常
    /// </summary>
    public class SearchException : Exception
    {
        public SearchException(string message) : base(message) { }
        public SearchException(string message, Exception innerException) : base(message, innerException) { }
    }
}
